package app

import (
	"context"
	"log"
	"net/http"
	"os"
	"os/signal"
	"syscall"
	"time"

	"gitee.com/huangxinbo/xcas/internal/app"
	_ "gitee.com/huangxinbo/xcas/internal/app/docs" // Import docs package
	"github.com/spf13/cobra"
	"go.uber.org/zap"
)

var (
	StartCmd = &cobra.Command{
		Use:     "app",
		Short:   "Start cas server",
		Example: "cas app",
		Run: func(cmd *cobra.Command, args []string) {
			run()
		},
	}
)

// @title						XCAS API
// @version					1.0.0
// @description				XCAS API Documentation
// @host						localhost:8080
// @BasePath					/
// @securityDefinitions.apikey	BearerAuth
// @in							header
// @name						Authorization
// @description				Bearer token authentication. Format: "Bearer {access_token}". Example: "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
func run() {
	app, err := app.NewApp()
	if err != nil {
		log.Fatalf("Failed to new app: %v", err)
	}

	// Start HTTP server
	go func() {
		if err := app.Run(); err != nil && err != http.ErrServerClosed {
			app.Logger.Error("Failed to start server", zap.Error(err))
			os.Exit(1)
		}
	}()

	// Wait for interrupt signal
	quit := make(chan os.Signal, 1)
	signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
	<-quit

	app.Logger.Info("Shutting down server...")

	// Create a context to notify server to finish current requests in 3 seconds
	ctx, cancel := context.WithTimeout(context.Background(), 3*time.Second)
	defer cancel()
	if err := app.Shutdown(ctx); err != nil {
		app.Logger.Error("Server shutdown with error", zap.Error(err))
	} else {
		app.Logger.Info("Server shutdown gracefully")
	}
	app.Logger.Info("Server exit.")
}
